import * as http from 'http'
import ctls from './Ctls'
import { METHOD_METADATA, PATH_METADATA } from './decorators'
import StrUtil from './utils/StrUtil'
export default class Router {
    static obj = {} as any
    static controller(
        req: http.IncomingMessage,
        res: http.ServerResponse<http.IncomingMessage> & {
            req: http.IncomingMessage
        },
        data: any
    ) {
        const methodName: any = req.method

        if (methodName === 'GET') {
            data = StrUtil.getParam(req.url)
        }
        let url = req.url + ''
        if (url.indexOf('?') !== -1) url = url.split('?')[0]

        const ctl = Router.obj[url]
        if (ctl) {
            let ctype = req.headers['Content-Type']
            if (!ctype) ctype = 'application/json'
            if (ctl.httpMethod.toLocaleUpperCase() != methodName) {
                res.writeHead(405, { 'Content-Type': `${ctype}; charset=utf-8` })
                res.end()
                return
            }
            res.writeHead(200, {
                'Content-Type': `${ctype}; charset=utf-8`,
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Credentials': 'true'
            })
            ;(async () => {
                res.end(await ctl.class[ctl.methodName](data, req, res))
            })()
        } else {
            res.writeHead(404, { 'Content-Type': 'text/plain' })
            res.end()
        }
    }

    static async init() {
        const ctlsObj: any = ctls

        Object.keys(ctlsObj).forEach((ctlsName) => {
            const ctlClass = ctlsObj[ctlsName]

            // 获取所有方法名
            const methods = Object.getOwnPropertyNames(ctlClass.prototype)
            // 获取类上面的路由装饰器
            const controllerName = Reflect.getMetadata(PATH_METADATA, ctlClass)
            console.log(controllerName)
            methods.forEach((methodName) => {
                // 获取方法上的路由装饰器
                let routePath = Reflect.getMetadata(PATH_METADATA, ctlClass.prototype, methodName)
                if (routePath) {
                    if (!routePath.startsWith('/')) {
                        routePath = `${controllerName}/${routePath}`
                    }
                    // 获取方法上的 HTTP 方法装饰器
                    const httpMethod = Reflect.getMetadata(METHOD_METADATA, ctlClass.prototype, methodName)
                    if (Router.obj[routePath]) return new Error('出现重复的路由地址')
                    // 将方法添加到路由
                    Router.obj[routePath] = {
                        class: new ctlClass(),
                        httpMethod: httpMethod,
                        methodName: methodName
                    }
                }
            })
        })
    }
}
